package top.korori.sv.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.RandomUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import top.korori.common.exception.BizException;
import top.korori.common.utils.RedisCache;
import top.korori.sv.constant.AuthConstant;
import top.korori.sv.constant.CacheConstant;
import top.korori.sv.entity.SvUser;
import top.korori.sv.entity.bo.SvLoginBo;
import top.korori.sv.entity.model.LoginUser;
import top.korori.sv.service.SvAuthService;
import top.korori.sv.service.SvUserService;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 身份认证、
 */
@Service
public class SvAuthServiceImpl implements SvAuthService {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private SvUserService svUserService;


    @Value("${sv.token.secret}")
    public String secret;

    @Value("${sv.token.expireTime}")
    public Long expireTime;

    @Override
    public String login(SvLoginBo svLoginBo) {

        if (!Validator.isMobile(svLoginBo.getAccount())) {
            BizException.cast("请输入正确的手机号");
        }

        //验证码密码都没有输入
        if (ObjUtil.isEmpty(svLoginBo.getPassword()) && ObjUtil.isEmpty(svLoginBo.getCode())) {
            BizException.cast("请输入密码或验证码");
        }

        SvUser svUser = svUserService.getByAccount(svLoginBo.getAccount());

        //如果输入了密码
        if (ObjUtil.isNotEmpty(svLoginBo.getPassword())) {

            //用户不存在
            if (ObjUtil.isNull(svUser)) {
                BizException.cast("你输入的账号不存在");
            }

            //密码错误
            if (ObjUtil.notEqual(svLoginBo.getPassword(), svUser.getPassword())) {
                BizException.cast("你输入的密码有误");
            }

            //如果上面判断通过,说明用户存且密码正确,直接创建令牌
            return createToken(svUser);
        }


        String code = redisCache.get(CacheConstant.SV_PHONE_CODE + svLoginBo.getAccount());

        if (ObjUtil.isEmpty(code)) {
            BizException.cast("你输入的验证码已过期");
        }

        if (ObjUtil.notEqual(code, svLoginBo.getCode())) {
            BizException.cast("你输入的验证码有误");
        }

        if (ObjUtil.isNotNull(svUser)) {
            return createToken(svUser);
        }


        if (ObjUtil.isNull(svUser)) {

            RandomUtil.randomString(8);

            SvUser user = new SvUser();
            user.setUserName(getOnlyUserName());
            user.setPhone(svLoginBo.getAccount());
            svUserService.save(user);
            return createToken(user);
        }

        return createToken(svUser);

    }

    /**
     * 获取唯一用户名
     *
     * @return 用户名
     */
    private String getOnlyUserName() {
        String userName = "用户" + RandomUtil.randomString(8);
        SvUser svUser = svUserService.getByUserName(userName);
        if (ObjUtil.isNotNull(svUser)) {
            return getOnlyUserName();
        }
        return userName;
    }

    private String createToken(SvUser svUser) {


        JWTCreator.Builder builder = JWT.create();
        builder.withClaim(AuthConstant.JWT_UID, svUser.getUserId());

        String token = builder.withIssuedAt(new Date()) //发行时间
                .sign(Algorithm.HMAC256(secret));

        LoginUser<SvUser> loginUser = new LoginUser<>();

        loginUser.setUserId(svUser.getUserId());
        loginUser.setUser(svUser);

        redisCache.set(CacheConstant.SV_USER_INFO + svUser.getUserId(), loginUser, expireTime, TimeUnit.MINUTES);
        return token;
    }


    @Override
    public String sendLoginCode(String phone) {
        int num = RandomUtil.randomInt(9999);
        String code = String.format("%04d", num);
        redisCache.set(CacheConstant.SV_PHONE_CODE + phone, code, 15, TimeUnit.MINUTES);
        return "【视频科技】" + code + "短视频验证码,15分钟有效,仅用于登录验证,请勿告知他人。";
    }


}






























